
package com.oahcfly.chgame.core.helper;

import java.util.Random;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Action;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.Pool.Poolable;
import com.badlogic.gdx.utils.Pools;
import com.oahcfly.chgame.core.Chao;
import com.oahcfly.chgame.core.actions.CHScheduleAction;
import com.oahcfly.chgame.core.mvc.CHActor;

/** <pre>
 * 
 * 可自由扩展的粒子播放器
 * <设置粒子图片路径即可>
 * date: 2015年3月26日
 * </pre>
 * 
 * @author caohao */
public class CHAutoParticle implements Poolable {
	private Random random = new Random();

	private Pool<CHActor> starPool = null;

	private Array<CHActor> particleActorArray;

	private int cradius = 100;
	private int num = 30;
	private Color particleColor = null;
	private float duration = 0.3f;

	public void setRadius (int radius) {
		cradius = radius;
	}

	private String imgString;

	public void setImagePath (final String imgPath) {
		this.imgString = imgPath;
		starPool = (Pool<CHActor>)Pools.get(CHActor.class);
		particleActorArray = new Array<CHActor>();
	}

	private CHActor getActor () {
		CHActor chActor = starPool.obtain();
		Texture texture = Chao.game.getTexture(imgString);
		chActor.setBgTexture(texture);
		chActor.setSize(50, 50);
		chActor.setName(CHAutoParticle.class.getSimpleName());
		chActor.setOrigin(com.badlogic.gdx.utils.Align.center);
		if (particleColor != null) {
			chActor.setColor(particleColor);
		} else {
			float r = (float)((Math.random() * 0.4f) + 0.7f);
			float g = (float)((Math.random() * 0.4f) + 0.7f);
			float b = (float)((Math.random() * 0.4f) + 0.7f);
			chActor.setColor(r, g, b, 1);
		}
		return chActor;
	}

	/** @param imgPath 图片路径 */
	public CHAutoParticle (final String imgPath) {
		setImagePath(imgPath);
	}

	public CHAutoParticle () {

	}

	public void playCircleParticle (Stage stage, float centerX, float centerY) {
		this.playCircleParticle(stage, centerX, centerY, null);
	}

	/** <pre>
	 *   <由中心向周围扩散并且旋转缩小>
	 *    播放粒子效果
	 * date: 2015年3月26日
	 * </pre>
	 * 
	 * @author caohao
	 * @param stage
	 * @param centerX 中心点位置X
	 * @param centerY 中心点位置Y */
	public void playCircleParticle (Stage stage, float centerX, float centerY, final Runnable callback) {
		// 半径范围
		float initRadius = cradius;
		// 星星数量
		float starNum = num;
		float initStarDuration = duration;
		for (int i = 0; i < starNum; i++) {
			// 随机角度
			int degree = random.nextInt(360) + 1;
			// 随机运行时间
			float starDuration = (float)(initStarDuration + random.nextInt(5) / 10f);
			// 随机半径
			float radius = initRadius + random.nextInt(10);
			final CHActor starImg = getActor();
			starImg.setPosition(centerX, centerY, Align.center);
			starImg.setScale(1);
			particleActorArray.add(starImg);
			// 目标点
			float targetX = centerX + (float)(radius * Math.cos(Math.toRadians(degree)));
			float targetY = centerY + (float)(radius * Math.sin(Math.toRadians(degree)));

			final boolean islast = i == starNum - 1;
			// 运动同时进行旋转，缩小
			Action parallelAction = Actions.parallel(Actions.moveTo(targetX, targetY, starDuration),
				Actions.rotateBy(360, starDuration), Actions.scaleTo(0.1f, 0.1f, starDuration));
			starImg.addAction(Actions.sequence(parallelAction, Actions.run(new Runnable() {

				@Override
				public void run () {
					// 释放加移除
					starPool.free(starImg);
					starImg.remove();
					if (islast) {
						Pool<CHAutoParticle> pool = Pools.get(CHAutoParticle.class);
						pool.free(CHAutoParticle.this);
						if (callback != null) {
							callback.run();
						}
					}
				}
			})));
			stage.addActor(starImg);
		}
	}

	/** <pre>
	 * <烟花效果>
	 * 
	 * date: 2015年3月26日
	 * </pre>
	 * 
	 * @author caohao
	 * @param stage
	 * @param rangeRectangle 烟花范围 */
	public void playFireWorks (final Stage stage, final Rectangle rangeRectangle, final int playCount,
		final Runnable callbackRunnable) {
		Action runnableAction = Actions.run(new Runnable() {

			int count;

			@Override
			public void run () {
				count++;
				if (count > playCount) {
					for (Action action : stage.getRoot().getActions()) {
						if (action instanceof CHScheduleAction) {
							((CHScheduleAction)action).finish();
						}
					}
					return;
				}
				for (int i = 0; i < 10; i++) {
					int x = (int)(random.nextInt((int)rangeRectangle.width) + rangeRectangle.x);
					int y = (int)(random.nextInt((int)rangeRectangle.height) + rangeRectangle.y);
					playCircleParticle(stage, x, y, null);
				}
			}
		});

		Runnable runnable = new Runnable() {

			@Override
			public void run () {
				// TODO Auto-generated method stub
				if (callbackRunnable != null) {
					callbackRunnable.run();
				}

				Pool<CHAutoParticle> pool = Pools.get(CHAutoParticle.class);
				pool.free(CHAutoParticle.this);

			}
		};
		CHScheduleAction scheduleAction = new CHScheduleAction(0.5f, playCount, runnableAction);
		scheduleAction.setCallbackRunnable(runnable);
		stage.addAction(scheduleAction);
	}

	@Override
	public void reset () {
		// TODO Auto-generated method stub
		cradius = 100;
		num = 30;
		duration = 0.3f;
		particleColor = null;
		particleActorArray = null;
		if (starPool != null) {
			starPool.clear();
		}
	}

	public static CHAutoParticle obtain (String imgPath) {
		Pool<CHAutoParticle> pool = Pools.get(CHAutoParticle.class);
		CHAutoParticle chAutoParticle = pool.obtain();
		chAutoParticle.setImagePath(imgPath);
		return chAutoParticle;
	}

	public void setParticleNum (int num) {
		this.num = num;
	}

	public void setParticleColor (Color particleColor) {
		this.particleColor = particleColor;
	}

	public void setDuration (float duration) {
		this.duration = duration;
	}

}
